package com.meihuayishu.backend.util;

import com.meihuayishu.backend.entity.DivinationFeedback;
import com.meihuayishu.backend.repository.FeedbackRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 占卜准确性分析器
 * 分析用户反馈数据，提供准确性统计和调整建议
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class DivinationAccuracyAnalyzer {
    
    private final FeedbackRepository feedbackRepository;
    private final EnhancedCityElementData cityElementData;
    
    // 缓存分析结果（城市 -> 卦象 -> 准确率）
    private final Map<String, Map<String, Double>> cityHexagramAccuracyCache = new HashMap<>();
    
    // 缓存分析结果（心情 -> 卦象 -> 准确率）
    private final Map<String, Map<String, Double>> moodHexagramAccuracyCache = new HashMap<>();
    
    // 上次分析时间
    private LocalDateTime lastAnalysisTime;
    
    /**
     * 分析城市与卦象的准确性关联
     * @return 城市卦象准确率映射
     */
    public Map<String, Map<String, Double>> analyzeCityHexagramAccuracy() {
        // 如果缓存有效且不超过1小时，直接返回缓存结果
        if (lastAnalysisTime != null && 
            ChronoUnit.HOURS.between(lastAnalysisTime, LocalDateTime.now()) < 1 &&
            !cityHexagramAccuracyCache.isEmpty()) {
            return cityHexagramAccuracyCache;
        }
        
        // 获取所有不同的城市
        List<String> cities = feedbackRepository.findDistinctUserCity();
        
        // 获取所有不同的卦象
        List<String> hexagrams = feedbackRepository.findDistinctOriginalHexagram();
        
        Map<String, Map<String, Double>> result = new HashMap<>();
        
        // 分析每个城市对每个卦象的准确率
        for (String city : cities) {
            if (city == null || city.isEmpty()) continue;
            
            Map<String, Double> hexagramAccuracy = new HashMap<>();
            
            for (String hexagram : hexagrams) {
                if (hexagram == null || hexagram.isEmpty()) continue;
                
                // 查询该城市该卦象的反馈
                List<DivinationFeedback> feedbacks = feedbackRepository.findByUserCityAndOriginalHexagram(city, hexagram);
                
                if (feedbacks.isEmpty()) continue;
                
                // 计算准确率
                long accurateCount = feedbacks.stream()
                    .filter(f -> Boolean.TRUE.equals(f.getIsAccurate()))
                    .count();
                
                double accuracy = (double) accurateCount / feedbacks.size();
                hexagramAccuracy.put(hexagram, accuracy);
                
                // 根据准确率调整城市卦象权重
                adjustCityHexagramWeight(city, hexagram, accuracy);
            }
            
            if (!hexagramAccuracy.isEmpty()) {
                result.put(city, hexagramAccuracy);
            }
        }
        
        // 更新缓存和分析时间
        cityHexagramAccuracyCache.clear();
        cityHexagramAccuracyCache.putAll(result);
        lastAnalysisTime = LocalDateTime.now();
        
        return result;
    }
    
    /**
     * 分析心情与卦象的准确性关联
     * @return 心情卦象准确率映射
     */
    public Map<String, Map<String, Double>> analyzeMoodHexagramAccuracy() {
        // 如果缓存有效且不超过1小时，直接返回缓存结果
        if (lastAnalysisTime != null && 
            ChronoUnit.HOURS.between(lastAnalysisTime, LocalDateTime.now()) < 1 &&
            !moodHexagramAccuracyCache.isEmpty()) {
            return moodHexagramAccuracyCache;
        }
        
        // 获取所有不同的心情
        List<String> moods = feedbackRepository.findDistinctUserMood();
        
        // 获取所有不同的卦象
        List<String> hexagrams = feedbackRepository.findDistinctOriginalHexagram();
        
        Map<String, Map<String, Double>> result = new HashMap<>();
        
        // 分析每个心情对每个卦象的准确率
        for (String mood : moods) {
            if (mood == null || mood.isEmpty()) continue;
            
            Map<String, Double> hexagramAccuracy = new HashMap<>();
            
            for (String hexagram : hexagrams) {
                if (hexagram == null || hexagram.isEmpty()) continue;
                
                // 统计该心情该卦象的总反馈数
                long totalCount = feedbackRepository.countByUserMoodAndOriginalHexagram(mood, hexagram);
                
                if (totalCount == 0) continue;
                
                // 统计准确反馈数
                long accurateCount = feedbackRepository.countByUserMoodAndOriginalHexagramAndIsAccurate(mood, hexagram, true);
                
                double accuracy = (double) accurateCount / totalCount;
                hexagramAccuracy.put(hexagram, accuracy);
            }
            
            if (!hexagramAccuracy.isEmpty()) {
                result.put(mood, hexagramAccuracy);
            }
        }
        
        // 更新缓存和分析时间
        moodHexagramAccuracyCache.clear();
        moodHexagramAccuracyCache.putAll(result);
        lastAnalysisTime = LocalDateTime.now();
        
        return result;
    }
    
    /**
     * 获取用户的占卜准确率
     * @param userId 用户ID
     * @return 准确率（0-1之间的小数）
     */
    public double getUserAccuracyRate(Long userId) {
        long totalCount = feedbackRepository.countByUserId(userId);
        if (totalCount == 0) {
            return 0.0;
        }
        
        long accurateCount = feedbackRepository.countByUserIdAndIsAccurate(userId, true);
        return (double) accurateCount / totalCount;
    }
    
    /**
     * 根据准确率调整城市卦象权重
     * @param city 城市
     * @param hexagram 卦象
     * @param accuracy 准确率
     */
    private void adjustCityHexagramWeight(String city, String hexagram, double accuracy) {
        // 根据准确率调整权重
        // 准确率高于0.7，增加权重；低于0.3，减少权重
        if (accuracy > 0.7) {
            cityElementData.adjustCityHexagramWeight(city, hexagram, true);
        } else if (accuracy < 0.3) {
            cityElementData.adjustCityHexagramWeight(city, hexagram, false);
        }
    }
    
    /**
     * 获取用户最近的占卜反馈
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 反馈列表
     */
    public List<DivinationFeedback> getUserRecentFeedback(Long userId, int limit) {
        return feedbackRepository.findByUserIdOrderByCreatedAtDesc(userId).stream()
            .limit(limit)
            .collect(Collectors.toList());
    }
    
    /**
     * 清除分析缓存
     */
    public void clearAnalysisCache() {
        cityHexagramAccuracyCache.clear();
        moodHexagramAccuracyCache.clear();
        lastAnalysisTime = null;
    }
}